﻿using System;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace ProjectNocturnalFool
{
    /// <summary>
    /// draws the TileImages based on the "GameLogic.GameBoardLogic.getTiles()" TileSet
    /// 
    /// </summary>
    class TileDrawer
    {
        private Texture2D mouseMap; //does a colour overlay test to see which diamond-shaped tile area mouse is in
        private Texture2D highlighter; //a simple semi-transparent square to show selection/aoe/etc
        
        int squaresAcross = 20;
        int squaresDown = 40;



        #region Constructor
        public TileDrawer(Texture2D _mouseMap, Texture2D _highlighter)
        {
            mouseMap = _mouseMap;
            highlighter = _highlighter;

        }
        #endregion


        #region Methods
        /// <summary>
        /// returns a point on the TileSet
        /// </summary>
        /// <param name="worldPoint"></param>
        /// <param name="localPoint"></param>
        /// <returns></returns>
        public Point WorldToTile(Point worldPoint, out Point localPoint)
        {
            Point tile = new Point(
               (int)(worldPoint.X / mouseMap.Width),
               ((int)(worldPoint.Y / mouseMap.Height)) * 2
               );

            int localPointX = worldPoint.X % mouseMap.Width;
            int localPointY = worldPoint.Y % mouseMap.Height;

            int dx = 0;
            int dy = 0;

            uint[] myUint = new uint[1];

            if (new Rectangle(0, 0, mouseMap.Width, mouseMap.Height).Contains(localPointX, localPointY))
            {
                mouseMap.GetData(0, new Rectangle(localPointX, localPointY, 1, 1), myUint, 0, 1);

                if (myUint[0] == 0xFF0000FF) // Red
                {
                    dx = -1;
                    dy = -1;
                    localPointX = localPointX + (mouseMap.Width / 2);
                    localPointY = localPointY + (mouseMap.Height / 2);
                }

                if (myUint[0] == 0xFF00FF00) // Green
                {
                    dx = -1;
                    localPointX = localPointX + (mouseMap.Width / 2);
                    dy = 1;
                    localPointY = localPointY - (mouseMap.Height / 2);
                }

                if (myUint[0] == 0xFF00FFFF) // Yellow
                {
                    dy = -1;
                    localPointX = localPointX - (mouseMap.Width / 2);
                    localPointY = localPointY + (mouseMap.Height / 2);
                }

                if (myUint[0] == 0xFFFF0000) // Blue
                {
                    dy = +1;
                    localPointX = localPointX - (mouseMap.Width / 2);
                    localPointY = localPointY - (mouseMap.Height / 2);
                }
            }

            tile.X += dx;
            tile.Y += dy;// -2;

            localPoint = new Point(localPointX, localPointY);
            return tile;
        }
        /// <summary>
        /// method for returning 1 value
        /// </summary>
        /// <param name="worldPoint"></param>
        /// <returns></returns>
        public Point WorldToTile(Point worldPoint)
        {
            Point dummy;
            return WorldToTile(worldPoint, out dummy);
        }

        #endregion

        #region Draw

        public void Draw(GameTime gameTime){
            Vector2 firstSquare = new Vector2(
                                                (((Camera.Location.X) / TileImage.tileImageStepX) - 1), 
                                                (((Camera.Location.Y) / TileImage.tileImageStepY)  - 1) 
                                                );


            int firstX = (int)firstSquare.X;
            int firstY = (int)firstSquare.Y;


            //DebugMgr.Instance.addDebug("firstSquareX - " + (firstX).ToString(), 7);
            //DebugMgr.Instance.addDebug("firstSquareY - " + (firstY).ToString(), 8);

            Vector2 squareOffset = new Vector2(Camera.location.X % TileImage.tileImageStepX, Camera.location.Y % TileImage.tileImageStepY);
            int offsetX = (int)squareOffset.X;
            int offsetY = (int)squareOffset.Y;

            //float maxDepth = ((GameLogic.Instance.gameBoardLogic.tiles.tileSetWidth + 1) * ((GameLogic.Instance.gameBoardLogic.tiles.tileSetHeight + 1) * TileImage.tileImageWidth)) * 10;
            //float depthOffset;
            //String allXLocs = "";
            //String allYLocs = "";
            for (int y = 0; y < squaresDown; y++)
            {
                int rowOffset = 0;
                if ((firstY + y) % 2 == 1)
                    rowOffset = TileImage.oddRowXOffset;

                for (int x = 0; x < squaresAcross; x++)
                {
                    int mapx = (firstX + x);
                    int mapy = (firstY + y);
                    //depthOffset = 0.7f -((mapx + (mapy * TileImage.tileImageWidth)) / maxDepth);

                    //DebugMgr.Instance.addDebug("depth - " + (0.7f -((1 + (7 * TileImage.tileImageWidth)) / maxDepth)).ToString(), 3);
                    if ((mapx >= GameLogic.Instance.gameBoardLogic.tiles.tileSetWidth) || (mapy >= GameLogic.Instance.gameBoardLogic.tiles.tileSetHeight)
                         || mapx < 0 || mapy < 0
                        )
                        continue;


                    
                    foreach (int tileID in GameLogic.Instance.gameBoardLogic.tiles.rows[mapy].columns[mapx].baseTileImages)
                    {
                        //allXLocs += ((mapx * TileImage.tileImageStepX) + rowOffset).ToString()+",";
                        //allYLocs += ((mapy - 2) * TileImage.tileImageStepY).ToString()+",";
                        TacticsGame.Instance.spriteBatch.Draw(
                            TileImage.imageSheet,
                            Camera.WorldToScreen(
                                new Vector2(
                                     (mapx * TileImage.tileImageStepX) + rowOffset,
                                     (mapy - 2) * TileImage.tileImageStepY
                                     )
                                    ),
                            TileImage.GetSourceRectangle(tileID),
                            Color.White,
                            0.0f,
                            Vector2.Zero,
                            Camera.scale,
                            SpriteEffects.None,
                            1.0f);
                    }
                    int heightRow = 0;
                    foreach (int tileID in GameLogic.Instance.gameBoardLogic.tiles.rows[mapy].columns[mapx].heightTileImages)
                    {
                        
                        TacticsGame.Instance.spriteBatch.Draw(
                            TileImage.imageSheet,
                            Camera.WorldToScreen(
                                new Vector2(
                                    (mapx * TileImage.tileImageStepX) + rowOffset,
                                    (mapy-2) * TileImage.tileImageStepY - (heightRow * TileImage.heightTileImageOffset))),
                            TileImage.GetSourceRectangle(tileID),
                            Color.White,
                            0.0f,
                            Vector2.Zero,
                            Camera.scale,
                            SpriteEffects.None,
                            GameLogic.Instance.gameBoardLogic.tiles.getDrawDepth(mapy, mapx, heightRow));
                            //depthOffset - ((float)heightRow * Constants.heightRowDepthMod));

                        //DebugMgr.Instance.addDebug("depth - " + depthOffset.ToString(), 3);
                        //DebugMgr.Instance.addDebug("depth - " +  (depthOffset - ((float)heightRow * heightRowDepthMod)).ToString(), 4);
            
                        heightRow++;
                        //DebugMgr.Instance.addDebug("heightTileDepth: " + GameLogic.Instance.gameBoardLogic.tiles.getDrawDepth(mapy, mapx, heightRow), 3);
                    
                    }
                    heightRow--;
                    //draws available selectable tiles
                    if (GameLogic.Instance.gameBoardLogic.tiles.rows[mapy].columns[mapx].mouseSelected)
                    {
                        TacticsGame.Instance.spriteBatch.Draw(
                                highlighter,
                                Camera.WorldToScreen(
                                    new Vector2(
                                        (mapx * TileImage.tileImageStepX) + rowOffset,
                                        (mapy - 2) * TileImage.tileImageStepY - (heightRow * TileImage.heightTileImageOffset))),
                                new Rectangle(0, 0, 64, 32),
                                Color.White * 0.4f,
                                0.0f,
                                Vector2.Zero,
                                Camera.scale,
                                SpriteEffects.None,
                                GameLogic.Instance.gameBoardLogic.tiles.getDrawDepth(mapy, mapx, heightRow) - Constants.selectorDepthMod);
                    }
                    
                    //draws selected tiles
                    else if (GameLogic.Instance.gameBoardLogic.tiles.rows[mapy].columns[mapx].availableSelection)
                    {
                        TacticsGame.Instance.spriteBatch.Draw(
                                highlighter,
                                Camera.WorldToScreen(
                                    new Vector2(
                                        (mapx * TileImage.tileImageStepX) + rowOffset,
                                        (mapy - 2) * TileImage.tileImageStepY - (heightRow * TileImage.heightTileImageOffset))),
                                new Rectangle(0, 0, 64, 32),
                                Color.Blue * 0.4f,
                                0.0f,
                                Vector2.Zero,
                                Camera.scale,
                                SpriteEffects.None,
                                GameLogic.Instance.gameBoardLogic.tiles.getDrawDepth(mapy, mapx, heightRow) - Constants.selectorDepthMod);
                    }
                    else if (GameLogic.Instance.gameBoardLogic.tiles.rows[mapy].columns[mapx].inAreaOfEffect)
                    {
                        TacticsGame.Instance.spriteBatch.Draw(
                                highlighter,
                                Camera.WorldToScreen(
                                    new Vector2(
                                        (mapx * TileImage.tileImageStepX) + rowOffset,
                                        (mapy - 2) * TileImage.tileImageStepY - (heightRow * TileImage.heightTileImageOffset))),
                                new Rectangle(0, 0, 64, 32),
                                Color.Blue * 0.4f,
                                0.0f,
                                Vector2.Zero,
                                Camera.scale,
                                SpriteEffects.None,
                                GameLogic.Instance.gameBoardLogic.tiles.getDrawDepth(mapy, mapx, heightRow) - Constants.selectorDepthMod);
                    }
                    
                   
                   

                    /*TODO use this area for topper tileImages (need to modify variables
                     * foreach (int tileID in myMap.Rows[y + firstY].Columns[x + firstX].TopperTiles)
                     {
                         TacticsGame.Instance.spriteBatch.Draw(
                             Tile.TileSetTexture,
                             Camera.WorldToScreen(
                                 new Vector2((mapx * Tile.TileStepX) + rowOffset, mapy * Tile.TileStepY)),
                             Tile.GetSourceRectangle(tileID),
                             Color.White,
                             0.0f,
                             Vector2.Zero,
                             1.0f,
                             SpriteEffects.None,
                             depthOffset - ((float)heightRow * heightRowDepthMod));
                     }*/
                }
            }
            //DebugMgr.Instance.addDebug("X" + allXLocs, 4);
            //DebugMgr.Instance.addDebug("Y" + allYLocs, 5);
            
        }

        #endregion

    }
}
